/*******************************************************************************
 **  Name: usart.cpp                                                          **
 **  Description:                                                             **
 **                                                                           **
 **  CDDL: Open Source Initiative (OSI) Approved License                      **
 **                                                                           **
 **  Copyright (c) 2009-2010 Barry "Gian" James  <bjames@munixos.net>         **
 **  All rights reserved.                                                     **
 **                                                                           **
 **  The contents of this file are subject to the terms of the CDDL:          **
 **  Common Development and Distribution License (the "License").             **
 **  You may not use this file except in compliance with the License.         **
 **                                                                           **
 **  You can obtain a copy of the license at $PROJECT_ROOT/LICENSE            **
 **  or http://www.opensolaris.org/os/licensing.  This code is Open Source    **
 **  and you are free to use it within the confines of the license, even      **
 **  for your own closed-source commercial projects, as long as you follow    **
 **  the terms set forth in the CDDL.                                         **
 **                                                                           **
 **  When distributing Covered Code, include this CDDL HEADER in each         **
 **  file and include the License file at $PROJECT_ROOT/LICENSE.              **
 **  If applicable, add the following below this CDDL HEADER, with the        **
 **  fields enclosed by brackets "[]" replaced with your own identifying      **
 **  information: Portions Copyright [yyyy] [name of copyright owner]         **
 **                                                                           **
 ******************************************************************************/
#define _MUNIX_USART_CPP_ID "$Id: //depot/munix/libmunix/trunk/usart.cpp#3 $"
// Modified $DateTime$ by $Author$

#include "common.h"
#include "usart.h"


USART::USART(uint32 b, uint8 d)
{
    baud = b;
    direction = d;
    rxBuff = new RingBuff(DEFAULT_RXBUFF_SZ);
    txBuff = new RingBuff(DEFAULT_TXBUFF_SZ);
}


USART::~USART() {
    if (rxBuff) delete rxBuff;
    if (txBuff) delete txBuff;
}

#if defined(USART_OPERATOR_STREAM)
// Stream Operator members
USART &
USART::operator << (USART & u)
{
    return *this;
}

USART &
USART::operator << (bool b)
{
    if (b)  tx((1+0x30));
    else    tx((0+0x30));
    return *this;
}

USART & endl(USART & u)
{
    u.tx('\r');
    u.tx('\n');
    return u;
}

USART &
USART::operator << (uint8 i)
{
    tx(i);
    return *this;
}
USART &
USART::operator << (uint16 i)
{
    tx(i);
    tx((i>>8));
    return *this;
}
USART &
USART::operator << (char c)
{
    tx(c);
    return *this;
}
USART &
USART::operator << (char * msg)
{
    WriteRAMStr(msg);
    return *this;
}
USART &
USART::operator << (int8_t i)
{
    tx(i);
    return *this;
}
USART &
USART::operator << (int16_t i)
{
     tx(i);
    tx((i>>8));
    return *this;

}
#if defined(USART_STREAM_LONG)
USART &
USART::operator << (int32_t i)
{
    tx(i);
    tx((i>>8));
    tx((i>>16));
    tx((i>>24));
    return *this;
}
USART &
USART::operator << (uint32_t i)
{
    tx(i);
    tx((i>>8));
    tx((i>>16));
    tx((i>>24));
    return *this;

}
#endif
#if defined(USART_STREAM_DOUBLE)
USART &
USART::operator << (float f)
{

}
USART &
USART::operator << (double d)
{

}
#endif

#if 0
// Operators for implicit type conversion
USART & operator << (USART & out,char c)
{
    out.tx(c);
    return out;
}
USART & operator << (USART &out,signed char c)
{
    out.tx(c);
    return out;
}
USART & operator << (USART &out, const signed char * c)
{
    USART::WriteLine((const char*)c);
    return out;
}
USART & operator << (USART &out, const unsigned char * c)
{
    out.WriteLine((const char*)c);
    return out;
}
#endif
USART & operator << (USART &out, char const __attribute__((__progmem__)) * msg)
{
    out.WriteLine(msg);
    return out;
}
#endif  /* USART_OPERATOR_STREAM */


bool
USART::Connect()
{
    if (direction & USART_RX) UCSR0B |= (1 << RXEN0);
    if (direction & USART_TX) UCSR0B |= (1 << TXEN0);

    ubrrval = ((F_CPU)/(16UL*baud) - 1UL);
    
    UBRR0L = (ubrrval & 0xFF);
    UBRR0H = (ubrrval >>8);

    return true;
}

void
USART::SendWord(uint8 a, wchar_t w) {
    char s = w & 0x00FF;
    tx(s);
    s = w & 0xFF00;
    tx(s);
}

wchar_t
USART::RecvWord() {
    wchar_t ret = rx();
    ret <<= 8;
    ret = rx();
    return ret;
}

